package umls.PathwayCommons;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.xpath.XPathExpressionException;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.tidy.Tidy;

public class PCommonsClient {
	
	static String urlStr = "http://www.pathwaycommons.org/pc/webservice.do";
	static JAXBContext jc;
	static Unmarshaller u;
	static Logger logger = Logger.getLogger("umls.interfaces.Pathways.Pathways");
	public PCommonsClient() {
		try {
			jc = JAXBContext
					.newInstance("umls.interfaces.pathways.server.jaxb");
			u = jc.createUnmarshaller();
		} catch (Exception e) {
			System.err.println(e.toString());
		}
	}

	private static Element getRootTable(Document element)
			throws XPathExpressionException {
		NodeList nl = (NodeList) element.getElementsByTagName("table");
		int length = nl.getLength();

		for (int i = 0; i < length; i++) {
			Element n = (Element) nl.item(i);
			// table cellpadding="2" cellspacing="0" border="0" width="100%">
			if (n.getTagName().equals("table")
					&& n.getAttribute("cellpadding").equals("2")
					&& n.getAttribute("border").equals("0")
					&& n.getAttribute("width").equals("100%"))
				return n;

		}
		return null;

	}
	
	public static List<String> getIDFromKeyword(String keyword,int percentage)
			throws IOException {
		URL query = new URL(
				"http://www.pathwaycommons.org/pc/webservice.do?version=3.0&q="
						+ URLEncoder.encode(keyword,  "UTF-8")
						+ "&format=html&cmd=get_by_keyword&snapshot_id=GLOBAL_FILTER_SETTINGS&record_type=PATHWAY");
		Tidy tidy = new Tidy();
		tidy.setQuiet(true);
		tidy.setShowWarnings(false);
		Document response = tidy.parseDOM(query.openStream(), null);
		List<String> result = new ArrayList<String>();
		Element table = null;
		try {
			table = getRootTable(response);
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		if (table==null)
			return result;
		NodeList nl = table.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			if (nl.item(i).getNodeName().equals("tr")
					&& ((Element) nl.item(i)).getAttribute("valign")
							.equalsIgnoreCase("top")) {

				NodeList img = ((Element) nl.item(i))
						.getElementsByTagName("img");
				// System.out.println(((Element)img.item(0)).getAttribute("width"));
				int affinity = Integer.parseInt(((Element) img.item(0))
						.getAttribute("width"));
				if (affinity >= percentage) {
					NodeList idlist = ((Element) nl.item(i))
							.getElementsByTagName("a");
					String[] CPATH_ID = ((Element) idlist.item(0))
							.getAttribute("href").split("=");
					result.add(CPATH_ID[1]);
				}
			}
		}
		return result;
	}
	
	public static List<String> getGenes(String process) throws IOException {
		List<String> result = new LinkedList<String>();
		result.add(process);
		List<String> IDs = getIDFromKeyword(process, 50);
		if (IDs==null) return result;
		for (String id : IDs) {
			result.addAll(getGeneFromIDs(id));
		}

		return result;
	}

	public static List<String> getGeneFromIDs(String id) throws IOException {
		BufferedReader rd = null;
		;
		
		// http://www.pathwaycommons.org/pc/webservice.do?version=2.0&cmd=get_record_by_cpath_id&q=826370&output=gsea&output_id_type=GENE_SYMBOL
		URL url = null;
		String address = null;
		try {
			 address = "http://www.pathwaycommons.org/pc/webservice.do?version=2.0&cmd=get_record_by_cpath_id&q="
					+ URLEncoder.encode(id,  "UTF-8") + "&output=gsea&output_id_type=GENE_SYMBOL";
			 url = new URL(address);
		} catch (MalformedURLException e) {
			logger.error("Pathways: encoding error for string "+ address);
			
		}
		URLConnection conn = url.openConnection();
		rd = new BufferedReader(
				new InputStreamReader(conn.getInputStream()));
		StringBuilder sb = new StringBuilder();
		String temp = null;
		while ((temp = rd.readLine()) != null) {
			sb.append(temp);
		}
		rd.close();
		// rd.readLine();
		String[] genes = sb.toString().split("\t");
		List<String> result = new LinkedList<String>();
		for (int i = 0; i < genes.length; i++)
			if (!genes[i].equalsIgnoreCase("NOT_SPECIFIED"))
				result.add(genes[i]);
		return result;
	}

}
